package comtacti.native.tests;
import utest.Assert;
import comtacti.native.AutoCffi;

class TestBasicCffi 
{
	public function new()
	{
		
	}
	
	public function setup():Void 
	{
		
	}
	
	public function test_CffiRawInput():Void
	{
		Assert.equals("Hi from Auto CFFI!", CffiInlinedCpp.sayHi());
	}
	
	public function test_CffiRawWithArgs():Void
	{
		Assert.equals("carpet", CffiInlinedCpp.sum("car", "pet"));
	}
	
	public function test_CffiManyArgs():Void 
	{
		Assert.equals(21 ,CffiInlinedCpp.sumMany(1,2,3,4,5,6));
	}
	
	public function test_CffiSecondFile():Void 
	{
		Assert.equals(10, CffiInlinedCpp2.getInt());
	}
	
	public function test_NoBodyCffi():Void 
	{
		Assert.equals(25, CffiInlinedCpp.helper_function(5));
	}
	
	public function test_ChangedNameCffi():Void 
	{
		Assert.equals(1000, CffiInlinedCpp.renamedFunction(10));
	}
}


@:cffi("ngate_test",type = Eager)
@:include("<stdio.h>")
@:include("<string.h>")
private class CffiInlinedCpp extends AutoCffi
{
	private static function __init__():Void 
	{
		untyped __cffi__('
		int helper_function(int i)
		{
			return i * i;
		}
		
		int helper_function2(int i)
		{
			return i * i * i;
		}
		');
	}
	
	public static function sayHi():String 
	{
		return untyped __cffi__("return alloc_string(\"Hi from Auto CFFI!\");\n");
	}
	
	public static function sum(str1:String, str2:String):String
	{
		return untyped __cffi__('
			int len1 = val_strlen(_str1);
			int len2 = val_strlen(_str2);
			char *str = (char*)malloc(len1 + len2 + 1);
			memcpy(str, str1, len1);
			memcpy(str + len1, str2, len2);
			str[len1 + len2] = 0;

			value ret = alloc_string(str);
			free(str);
			return ret;
		');
	}
	
	public static function sumMany(i1:Int, i2:Int, i3:Int, i4:Int, i5:Int, i6:Int):Int 
	{
		return untyped __cffi__('return alloc_int(i1 + i2 + i3 + i4 + i5 + i6);');
	}
	
	public static function helper_function(i:Int):Int;
	
	@:native("helper_function2")
	public static function renamedFunction(i:Int):Int;
}

@:cffi("ngate_test", type=Lazy)
@:include("invalid_header.h", ifdef="INVALID_DEF")
private class CffiInlinedCpp2 extends AutoCffi
{
	public static function getInt():Int 
	{
		return untyped __cffi__("return alloc_int(10);");
	}
}